<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="keywords" content="Hexo Theme Redefine">
    
    <meta name="author" content="xiaoeryu">
    <!-- preconnect -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

    
    <!--- Seo Part-->
    
    <link rel="canonical" href="https://xiaoeeyu.github.io/2023/09/14/art下一代壳通用解决方案/"/>
    <meta name="robots" content="index,follow">
    <meta name="googlebot" content="index,follow">
    <meta name="revisit-after" content="1 days">
    
    
    
        
        <meta name="description" content="虽然Dalvik的脱壳方案对现在的一些壳还有作用，不过它只能解决一些整体性加壳的加壳方案，所以接下来来了解一下ART下脱壳的原理 本章我们主要把从InMemoryDexClassLoader到DexClassLoader(进行dex2oat和直接加载dex)流程中涉及到的脱壳点过了一遍，并修改编译Android源码，测试了对一代壳的脱壳（未进行函数抽取）。">
<meta property="og:type" content="article">
<meta property="og:title" content="ART下一代壳通用解决方案">
<meta property="og:url" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/index.html">
<meta property="og:site_name" content="xiaoeryu">
<meta property="og:description" content="虽然Dalvik的脱壳方案对现在的一些壳还有作用，不过它只能解决一些整体性加壳的加壳方案，所以接下来来了解一下ART下脱壳的原理 本章我们主要把从InMemoryDexClassLoader到DexClassLoader(进行dex2oat和直接加载dex)流程中涉及到的脱壳点过了一遍，并修改编译Android源码，测试了对一代壳的脱壳（未进行函数抽取）。">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/90cdcec908d54bfd87192db00e958c31.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/15500a3fd1d8479e9d7b9201ebac36bf.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/f307d3cf398d44fab5bfba9c7f754d50.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/3f1965aec8444cc5a0c3471e8029fc1b.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/bfbd5c81b82a425b849dbc8959b4323f.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/18f5481a913c40c399bcc6b821fb1dd7.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/49b8e606b07349a09806e71737537bb7.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/a964c7a7e66a4d948b5cad864c7dda7d.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/38118ec4972940abba97d396e92f766f.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/285e5e9a4af64cc18e854f689832bf9b.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/705af8ca444b4b829cead6552e9f32c8.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/ef0f5de37be249939aa7c58b8345351a.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/bae600a1e8854b7d8de2944598969d7b.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/fb46b985d4e14caabb93487ab3a7ac2d.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/66388a6ace0d4f3285bf1e3eac0c717c.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/767e749de7304539991a6cd5570778a2.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/8d95260f03f148eca52b10ada0ec2def.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/fd5d812cc0f94332aa1ee0fd20eabc8f.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/602ad3058cd041f284ab93f15919f6b9.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/814cfc438b8742b289b5c09cba00f91a.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/9137cbafb7ce43ac8e31c5b70b5d44db.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/279958ab9f574ce7bfa29a409a7c1152.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/717abb01ef104175a1f982140846e1a4.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/68055090125040578491df01e7270006.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/dca319d8eed2475891c5553aa0ccc7c1.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/78af1ed4381d41c9a65627b7fb90451a.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/f96f774610974615979d1da4028e8282.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/685565d63eab45689917862f674c0877.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/b91c408ab7d94eccabc74fd8c25e457a.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/7ebe4507c02f4d22ac8c60cedb1512a6.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/26640609f1824503812f067d69ee2618.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/739d8cdc2a0b459f83f0ec8ab742007f.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/c4163c2dc34e432c96c7242933013e7f.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/e76a3f1a9e694adcb36b502c1bc38db2.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/4fc6a3f1260a40689379e96ecf593afc.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/b39c3705ca0e4fd49814759c128364d0.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/31e56ded535d46f58f875c328a22be25.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/69a05ede94354e57ad646644ae40cc5a.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/b395c12b8c394a03b3e960b8b22b8d6c.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/992ee61e4b454ba6a27a494650256912.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/718358cf7bd34210b037654507e26d85.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/2503e48477b340b88c222510ea31ba44.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914162835544.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/c352b1080cc14a9ca217dd89cb9a5f24.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914155304069.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914161213587.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/02ac72275c1c4dfc9aac6193ee5023de.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914155434953.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/c2844eb50c5b4fc08553de56a58df482.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/29e34c1fa4c84ace9e38e0b43754b4a5.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/1d1f3c5174b047bab0a248a1d950d9ea.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/688afadad884485c87adf0c50cddba50.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914155735045.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/8afea948022543abac1fdd8374ad207e.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914155936844.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/a2a9c8573cd34b38bf921c16a88118f6.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/b2662afa121249cf88b24d45bf494288.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/e7ca73439a1744b7bb096661dc57e77a.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/9098a19e7e524694a6568d75c17c6ff3.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/acaf40b185c045fcaeee04c603e2333a.png">
<meta property="og:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/4e3a19252a3547d19e10ae363f225748.png">
<meta property="article:published_time" content="2023-09-13T16:09:38.000Z">
<meta property="article:modified_time" content="2023-09-23T10:15:38.811Z">
<meta property="article:author" content="xiaoeryu">
<meta property="article:tag" content="Android脱壳">
<meta property="article:tag" content="学习笔记">
<meta property="article:tag" content="Android源码分析">
<meta property="article:tag" content="ART脱壳">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://xiaoeeyu.github.io/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/90cdcec908d54bfd87192db00e958c31.png">
    
    
    <!--- Icon Part-->
    <link rel="icon" type="image/png" href="/images/rabete.jpg" sizes="192x192">
    <link rel="apple-touch-icon" sizes="180x180" href="/images/rabete.jpg">
    <meta name="theme-color" content="#A31F34">
    <link rel="shortcut icon" href="/images/rabete.jpg">
    <!--- Page Info-->
    
    <title>
        
            ART下一代壳通用解决方案 | xiaoeryu
        
    </title>

    
<link rel="stylesheet" href="/fonts/Chillax/chillax.css">


    <!--- Inject Part-->
    

    
<link rel="stylesheet" href="/css/style.css">


    
        
<link rel="stylesheet" href="/css/build/tailwind.css">

    

    
<link rel="stylesheet" href="/fonts/GeistMono/geist-mono.css">

    
<link rel="stylesheet" href="/fonts/Geist/geist.css">

    <!--- Font Part-->
    
    
    
    
    
    

    <script id="hexo-configurations">
    window.config = {"hostname":"xiaoeeyu.github.io","root":"/","language":"zh-CN","path":"search.xml"};
    window.theme = {"articles":{"style":{"font_size":"16px","line_height":1.5,"image_border_radius":"14px","image_alignment":"center","image_caption":false,"link_icon":true,"delete_mask":false,"title_alignment":"left","headings_top_spacing":{"h1":"3.2rem","h2":"2.4rem","h3":"1.9rem","h4":"1.6rem","h5":"1.4rem","h6":"1.3rem"}},"word_count":{"enable":true,"count":true,"min2read":true},"author_label":{"enable":true,"auto":false,"list":[]},"code_block":{"copy":true,"style":"mac","highlight_theme":{"light":"github","dark":"vs2015"},"font":{"enable":false,"family":null,"url":null}},"toc":{"enable":true,"max_depth":4,"number":false,"expand":true,"init_open":true},"copyright":{"enable":true,"default":"cc_by_nc_sa"},"lazyload":true,"pangu_js":false,"recommendation":{"enable":false,"title":"推荐阅读","limit":3,"mobile_limit":2,"placeholder":"/images/ball-0101.jpg","skip_dirs":[]}},"colors":{"primary":"#A31F34","secondary":null,"default_mode":"light"},"global":{"fonts":{"chinese":{"enable":false,"family":null,"url":null},"english":{"enable":false,"family":null,"url":null},"title":{"enable":false,"family":null,"url":null}},"content_max_width":"1000px","sidebar_width":"210px","hover":{"shadow":true,"scale":false},"scroll_progress":{"bar":false,"percentage":true},"website_counter":{"url":"https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js","enable":true,"site_pv":true,"site_uv":true,"post_pv":true},"single_page":true,"preloader":{"enable":false,"custom_message":null},"open_graph":true,"google_analytics":{"enable":false,"id":null}},"home_banner":{"enable":true,"style":"fixed","image":{"light":"/images/wallhaven-jxl31y.png","dark":"/images/wallhaven-o5762l.png"},"title":"XIAOERYU","subtitle":{"text":["明心见性，拨云见日","Don't wait, to create"],"hitokoto":{"enable":false,"show_author":false,"api":"https://v1.hitokoto.cn"},"typing_speed":100,"backing_speed":80,"starting_delay":500,"backing_delay":1500,"loop":true,"smart_backspace":true},"text_color":{"light":"#fff","dark":"#d1d1b6"},"text_style":{"title_size":"2.8rem","subtitle_size":"1.5rem","line_height":1.2},"custom_font":{"enable":false,"family":null,"url":null},"social_links":{"enable":true,"style":"default","links":{"github":"https://github.com/xiaoeeyu","instagram":null,"zhihu":null,"twitter":null,"email":"xiaoeryu@163.com"},"qrs":{"weixin":null}}},"plugins":{"feed":{"enable":false},"aplayer":{"enable":false,"type":"fixed","audios":[{"name":null,"artist":null,"url":null,"cover":null,"lrc":null}]},"mermaid":{"enable":false,"version":"9.3.0"}},"version":"2.8.2","navbar":{"auto_hide":false,"color":{"left":"#f78736","right":"#367df7","transparency":35},"width":{"home":"1200px","pages":"1000px"},"links":{"Home":{"path":"/","icon":"fa-regular fa-house"},"Archives":{"path":"/archives","icon":"fa-regular fa-archive"}},"search":{"enable":true,"preload":true}},"page_templates":{"friends_column":2,"tags_style":"blur"},"home":{"sidebar":{"enable":true,"position":"left","first_item":"menu","announcement":null,"show_on_mobile":true,"links":null},"article_date_format":"auto","excerpt_length":200,"categories":{"enable":true,"limit":3},"tags":{"enable":true,"limit":3}},"footerStart":"2022/8/17 11:45:14"};
    window.lang_ago = {"second":"%s 秒前","minute":"%s 分钟前","hour":"%s 小时前","day":"%s 天前","week":"%s 周前","month":"%s 个月前","year":"%s 年前"};
    window.data = {"masonry":false};
  </script>
    
    <!--- Fontawesome Part-->
    
<link rel="stylesheet" href="/fontawesome/fontawesome.min.css">

    
<link rel="stylesheet" href="/fontawesome/brands.min.css">

    
<link rel="stylesheet" href="/fontawesome/solid.min.css">

    
<link rel="stylesheet" href="/fontawesome/regular.min.css">

    
    
    
    
<meta name="generator" content="Hexo 6.3.0">
<style>.github-emoji { position: relative; display: inline-block; width: 1.2em; min-height: 1.2em; overflow: hidden; vertical-align: top; color: transparent; }  .github-emoji > span { position: relative; z-index: 10; }  .github-emoji img, .github-emoji .fancybox { margin: 0 !important; padding: 0 !important; border: none !important; outline: none !important; text-decoration: none !important; user-select: none !important; cursor: auto !important; }  .github-emoji img { height: 1.2em !important; width: 1.2em !important; position: absolute !important; left: 50% !important; top: 50% !important; transform: translate(-50%, -50%) !important; user-select: none !important; cursor: auto !important; } .github-emoji-fallback { color: inherit; } .github-emoji-fallback img { opacity: 0 !important; }</style>
</head>



<body>
	<div class="progress-bar-container">
	

	
	<span class="pjax-progress-bar"></span>
	<!--        <span class="swup-progress-icon">-->
	<!--            <i class="fa-solid fa-circle-notch fa-spin"></i>-->
	<!--        </span>-->
	
</div>

<main class="page-container" id="swup">

	

	<div class="main-content-container flex flex-col justify-between min-h-dvh">
		<div class="main-content-header">
			<header class="navbar-container px-6 md:px-12">
    <div class="navbar-content transition-navbar ">
        <div class="left">
            
                <a class="logo-image h-8 w-8 sm:w-10 sm:h-10 mr-3" href="/">
                    <img src="/images/rabete.jpg" class="w-full h-full rounded-sm">
                </a>
            
            <a class="logo-title" href="/">
                
                xiaoeryu
                
            </a>
        </div>

        <div class="right">
            <!-- PC -->
            <div class="desktop">
                <ul class="navbar-list">
                    
                        
                            

                            <li class="navbar-item">
                                <!-- Menu -->
                                <a class=""
                                   href="/"
                                        >
                                    <i class="fa-regular fa-house fa-fw"></i>
                                    首页
                                    
                                </a>

                                <!-- Submenu -->
                                
                            </li>
                    
                        
                            

                            <li class="navbar-item">
                                <!-- Menu -->
                                <a class=""
                                   href="/archives"
                                        >
                                    <i class="fa-regular fa-archive fa-fw"></i>
                                    归档
                                    
                                </a>

                                <!-- Submenu -->
                                
                            </li>
                    
                    
                        <li class="navbar-item search search-popup-trigger">
                            <i class="fa-solid fa-magnifying-glass"></i>
                        </li>
                    
                </ul>
            </div>
            <!-- Mobile -->
            <div class="mobile">
                
                    <div class="icon-item search search-popup-trigger"><i class="fa-solid fa-magnifying-glass"></i>
                    </div>
                
                <div class="icon-item navbar-bar">
                    <div class="navbar-bar-middle"></div>
                </div>
            </div>
        </div>
    </div>

    <!-- Mobile sheet -->
    <div class="navbar-drawer h-dvh w-full absolute top-0 left-0 bg-background-color flex flex-col justify-between">
        <ul class="drawer-navbar-list flex flex-col px-4 justify-center items-start">
            
                
                    

                    <li class="drawer-navbar-item text-base my-1.5 flex flex-col w-full">
                        
                        <a class="py-1.5 px-2 flex flex-row items-center justify-between gap-1 hover:!text-primary active:!text-primary text-2xl font-semibold group border-b border-border-color hover:border-primary w-full "
                           href="/"
                        >
                            <span>
                                首页
                            </span>
                            
                                <i class="fa-regular fa-house fa-sm fa-fw"></i>
                            
                        </a>
                        

                        
                    </li>
            
                
                    

                    <li class="drawer-navbar-item text-base my-1.5 flex flex-col w-full">
                        
                        <a class="py-1.5 px-2 flex flex-row items-center justify-between gap-1 hover:!text-primary active:!text-primary text-2xl font-semibold group border-b border-border-color hover:border-primary w-full "
                           href="/archives"
                        >
                            <span>
                                归档
                            </span>
                            
                                <i class="fa-regular fa-archive fa-sm fa-fw"></i>
                            
                        </a>
                        

                        
                    </li>
            

            
            
        </ul>

        <div class="statistics flex justify-around my-2.5">
    <a class="item tag-count-item flex flex-col justify-center items-center w-20" href="/tags">
        <div class="number text-2xl sm:text-xl text-second-text-color font-semibold">92</div>
        <div class="label text-third-text-color text-sm">标签</div>
    </a>
    <a class="item tag-count-item flex flex-col justify-center items-center w-20" href="/categories">
        <div class="number text-2xl sm:text-xl text-second-text-color font-semibold">14</div>
        <div class="label text-third-text-color text-sm">分类</div>
    </a>
    <a class="item tag-count-item flex flex-col justify-center items-center w-20" href="/archives">
        <div class="number text-2xl sm:text-xl text-second-text-color font-semibold">112</div>
        <div class="label text-third-text-color text-sm">文章</div>
    </a>
</div>
    </div>

    <div class="window-mask"></div>

</header>


		</div>

		<div class="main-content-body transition-fade-up">
			

			<div class="main-content">
				<div class="post-page-container flex relative justify-between box-border w-full h-full">
	<div class="article-content-container">

		<div class="article-title relative w-full">
			
			<div class="w-full flex items-center pt-6 justify-start">
				<h1 class="article-title-regular text-second-text-color tracking-tight text-4xl md:text-6xl font-semibold px-2 sm:px-6 md:px-8 py-3">ART下一代壳通用解决方案</h1>
			</div>
			
		</div>

		
		<div class="article-header flex flex-row gap-2 items-center px-2 sm:px-6 md:px-8">
			<div class="avatar w-[46px] h-[46px] flex-shrink-0 rounded-medium border border-border-color p-[1px]">
				<img src="/images/rabete.jpg">
			</div>
			<div class="info flex flex-col justify-between">
				<div class="author flex items-center">
					<span class="name text-default-text-color text-lg font-semibold">xiaoeryu</span>
					
					<span class="author-label ml-1.5 text-xs px-2 py-0.5 rounded-small text-third-text-color border border-shadow-color-1">Lv5</span>
					
				</div>
				<div class="meta-info">
					<div class="article-meta-info">
    <span class="article-date article-meta-item">
        <i class="fa-regular fa-pen-fancy"></i>&nbsp;
        <span class="desktop">2023-09-14 00:09:38</span>
        <span class="mobile">2023-09-14 00:09:38</span>
        <span class="hover-info">创建</span>
    </span>
    
        <span class="article-date article-meta-item">
            <i class="fa-regular fa-wrench"></i>&nbsp;
            <span class="desktop">2023-09-23 18:15:38</span>
            <span class="mobile">2023-09-23 18:15:38</span>
            <span class="hover-info">更新</span>
        </span>
    

    
        <span class="article-categories article-meta-item">
            <i class="fa-regular fa-folders"></i>&nbsp;
            <ul>
                
                
                    
                        
                        <li>
                            <a href="/categories/Android%E9%80%86%E5%90%91/">Android逆向</a>&nbsp;
                        </li>
                    
                    
                
            </ul>
        </span>
    
    
        <span class="article-tags article-meta-item">
            <i class="fa-regular fa-tags"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/tags/Android%E8%84%B1%E5%A3%B3/">Android脱壳</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">学习笔记</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/Android%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/">Android源码分析</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/ART%E8%84%B1%E5%A3%B3/">ART脱壳</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    

    
    
    
    
        <span class="article-pv article-meta-item">
            <i class="fa-regular fa-eye"></i>&nbsp;<span id="busuanzi_value_page_pv"></span>
        </span>
    
</div>

				</div>
			</div>
		</div>
		

		


		<div class="article-content markdown-body px-2 sm:px-6 md:px-8 pb-8">
			<p>虽然Dalvik的脱壳方案对现在的一些壳还有作用，不过它只能解决一些整体性加壳的加壳方案，所以接下来来了解一下ART下脱壳的原理</p>
<p>本章我们主要把从InMemoryDexClassLoader到DexClassLoader(进行dex2oat和直接加载dex)流程中涉及到的脱壳点过了一遍，并修改编译Android源码，测试了对一代壳的脱壳（未进行函数抽取）。</p>
<span id="more"></span>

<h2 id="InMemoryDexClassLoader源码分析"><a href="#InMemoryDexClassLoader源码分析" class="headerlink" title="InMemoryDexClassLoader源码分析"></a>InMemoryDexClassLoader源码分析</h2><img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/90cdcec908d54bfd87192db00e958c31.png" class="" title="3e0209e82d4671484584240f43f7d582.png">

<p>先来分析InMemoryDexClassLoader的源码</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/15500a3fd1d8479e9d7b9201ebac36bf.png" class="" title="ae923e5a1854bfeb1d16715dfc2de1d6.png">

<p>从libcore中找到InMemoryDexClassLoader</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/f307d3cf398d44fab5bfba9c7f754d50.png" class="" title="c2bdc9c6c2baf1f3c297c5b3c5f5091b.png">

<ul>
<li><p>继承自InMemroyDexClassLoader，在函数体中调用了两次InMemoryDexClassLoader()，先跟进去看一下BaseDexClassLoader()</p>
</li>
<li><img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/3f1965aec8444cc5a0c3471e8029fc1b.png" class="" title="6a6df17d75bd9c2e4fa97ebc66d6d2b8.png">
</li>
<li><p>可以看到第一个参数传入的是ByteBuffer所以跟进这个方法</p>
</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/bfbd5c81b82a425b849dbc8959b4323f.png" class="" title="501890b458cd3424f8d8e98769b632d0.png">

<ul>
<li><p>进来之后先设置了一下父节点，然后new了一个DexPathList()，继续跟进</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/18f5481a913c40c399bcc6b821fb1dd7.png" class="" title="8c301d921ef027410e8aa44dac09ffa9.png">
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/49b8e606b07349a09806e71737537bb7.png" class="" title="2867390a4993eaa1d7bd8da451e0b991.png">
</li>
<li><p>进来之后忽略掉前面对参数的校验和对so库的一些操作，可以看到makeInMemoryDexElements()来处理了我们传入的dexFiles，继续跟进分析</p>
</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/a964c7a7e66a4d948b5cad864c7dda7d.png" class="" title="ba81f0172fa476ff1d689b060c190f55.png">

<ul>
<li><p>继续跟进DexFile()</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/38118ec4972940abba97d396e92f766f.png" class="" title="89c0e12305124c5cd76a4b5076ff8319.png">
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/285e5e9a4af64cc18e854f689832bf9b.png" class="" title="e976e6c6acc3af13603acf6b8e2c9ad2.png">
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/705af8ca444b4b829cead6552e9f32c8.png" class="" title="18b106d4982fde3cca3761aa8c06d842.png"></li>
<li><p>到了这里发现我们的<em>buf</em>传入了两个地方，它们调用完都进到native层了，接下来我们需要去<strong>native层</strong>继续跟踪</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/ef0f5de37be249939aa7c58b8345351a.png" class="" title="73227684eea0697b4ca8f7574c7248fe.png">
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/bae600a1e8854b7d8de2944598969d7b.png" class="" title="5737c5986c6749360b0f32a691e652fc.png">
</li>
<li><p>native层的代码我们在art里面查找可以直接检索到这两个函数，在<strong>图中237行</strong>的位置有memcpy()的动作，参数就有dex的起始地址和长度，所以我们在这个地方应该是可以将dex文件dump下来的。继续往下分析，可以看到我们找到的这两个函数在返回的时候都调用了*CreateSingleDexFileCookie()*参数传入了dex在内存中的地址，我们跟进去看一下</p>
</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/fb46b985d4e14caabb93487ab3a7ac2d.png" class="" title="f71e59c9ce1c7f676dcf5e8a29186fa2.png">

<ul>
<li><p>CreateSingleDexFileCookie()接收到传入的dex文件内存地址，dex地址给到了dex_file指针，之后进行操作调用ConvertDexFilesToJavaArray()将其转为java数组并返回。这里我们再跟一下CreateDexFile()看他对传入的dex文件是怎么操作的。</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/66388a6ace0d4f3285bf1e3eac0c717c.png" class="" title="e66015d333a966b5fcd86217582f0d76.png">

<ul>
<li><p>这边再跟进去看一下DexFile::Open()都进行了什么操作</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/767e749de7304539991a6cd5570778a2.png" class="" title="681b0d7a597cb734ebc2202e0c58bcdb.png">

<ul>
<li><p>这里又将参数传递给了OpenCommon()函数，再跟进去看一下</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/8d95260f03f148eca52b10ada0ec2def.png" class="" title="6afcdcb783831281fa9ed2271b12f4d0.png">
</li>
<li><p>可以看到这里创建DexFile对象的时候也传入了我们dex文件的起始地址和大小，再看一下</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/fd5d812cc0f94332aa1ee0fd20eabc8f.png" class="" title="26514b4500a0ebc7677556635a0e7392.png">
</li>
<li><p>通过对上面几个调用传参的分析，发现dex再加载的过程当中，有很多地方都涉及到了dex的起始地址和大小，我们也是可以获取这些信息来进行脱壳的，记录一下这些脱壳点api：</p>
<ol>
<li><p><code>static jobject CreateSingleDexFileCookie(JNIEnv* env, std::unique_ptr&lt;MemMap&gt; data)</code></p>
</li>
<li><p><code>static const DexFile* CreateDexFile(JNIEnv* env, std::unique_ptr&lt;MemMap&gt; dex_mem_map)</code></p>
</li>
<li><pre><code class="c++">std::unique_ptr&lt;const DexFile&gt; dex_file(DexFile::Open(location,
                                        0,
                                        std::move(dex_mem_map),
                                        /* verify */ true,
                                        /* verify_location */ true,
                                        &amp;error_message));
</code></pre>
</li>
<li><pre><code class="c++">std::unique_ptr&lt;DexFile&gt; dex_file = OpenCommon(map-&gt;Begin(),
                                         map-&gt;Size(),
                                         location,
                                         location_checksum,
                                         kNoOatDexFile,
                                         verify,
                                         verify_checksum,
                                         error_msg);
</code></pre>
</li>
<li><pre><code class="c++">DexFile::DexFile(const uint8_t* base,
                 size_t size,
                 const std::string&amp; location,
                 uint32_t location_checksum,
                 const OatDexFile* oat_dex_file)
</code></pre>
</li>
</ol>
</li>
</ul>
</li>
</ul>
</li>
<li><p>不过InMemoryDexClassLoader()并没有对内存中的DEX信息进行编译生成OAT文件，这点和DexClassLoader()不同</p>
</li>
</ul>
<h2 id="DexClassLoader加载源码流程分析"><a href="#DexClassLoader加载源码流程分析" class="headerlink" title="DexClassLoader加载源码流程分析"></a>DexClassLoader加载源码流程分析</h2><p>DexClassLoader加载源码分析的流程会较为复杂一些，因为这当中需要涉及到dex to oat的编译过程。</p>
<p>虽然有很多的一代壳会禁掉Dex2Oat，但是我们先分析一下，把两种情况分开来分析。</p>
<p>这个前面的分析过程几乎跟再Dalvik下面的流程是一样的，简单再过一遍，熟悉的可以忽略。</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/602ad3058cd041f284ab93f15919f6b9.png" class="" title="81200831e39166f366eeada6a4266146.png">

<ul>
<li><p>跟进</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/814cfc438b8742b289b5c09cba00f91a.png" class="" title="a86477b19dabd4bc5148bf33f802d324.png">
</li>
<li><p>跟进</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/9137cbafb7ce43ac8e31c5b70b5d44db.png" class="" title="f2e17f5268d99d02fc239f3dd1249f1c.png">
</li>
<li><p>跟进</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/279958ab9f574ce7bfa29a409a7c1152.png" class="" title="4f30489507233d5286afccd5e9a95885.png">
</li>
<li><p>继续跟进</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/717abb01ef104175a1f982140846e1a4.png" class="" title="d252312ac29eb5a33697654812ae26fd.png">
</li>
<li><p>继续跟进</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/68055090125040578491df01e7270006.png" class="" title="1f8d21dbce9bc2e997393a2a8b3c0603.png">
</li>
<li><p>跟进这个有五个参数的方法，因为我们传入的是五个参数</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/dca319d8eed2475891c5553aa0ccc7c1.png" class="" title="430bad6fd933cece7d48ca206aa598f9.png">
</li>
<li><p>继续跟进</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/78af1ed4381d41c9a65627b7fb90451a.png" class="" title="45803d157fece5902462b9f4e74a0e3c.png">
</li>
<li><p>到这里接下来呢就要进入<strong>native层</strong>了</p>
</li>
</ul>
<h3 id="跟进native层"><a href="#跟进native层" class="headerlink" title="跟进native层"></a>跟进native层</h3><img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/f96f774610974615979d1da4028e8282.png" class="" title="5603828804b52494b9c055dc5c0861ed.png">

<ul>
<li>在art目录下找到openDexFileNative()的实现</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/685565d63eab45689917862f674c0877.png" class="" title="ff4eda24bf669d490b2f11f9e31a35ea.png">

<ul>
<li>这里我们就可以看到函数中定义了一个OatFile指针变量，后面执行了OpenDexFilesFromOat()来进行生成oat的流程，我们跟进去看一下</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/b91c408ab7d94eccabc74fd8c25e457a.png" class="" title="edc508483f810009812117434da6ba09.png">

<ul>
<li>这段代码里面初始化了一个oat的对象，然后对oat是否为空进行了检测，因为第一次调用的时候它里面肯定是空的，然后进入switch()里面执行了MakeUpToData()方法跟进去看一下</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/7ebe4507c02f4d22ac8c60cedb1512a6.png" class="" title="87af31d8d1089f4857f6571c6c47cae8.png">

<ul>
<li>这里返回值是来自于GenerateOatFileNoChecks()，继续跟进看一下</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/26640609f1824503812f067d69ee2618.png" class="" title="5ed8908a9bed208fa5295c1ab3a10207.png">

<ul>
<li>进入该函数，进行了一些校验之后在下面我们可以看到有一个Dex2Oat()，这个函数名的意思很明确我们跟进去看一下<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/739d8cdc2a0b459f83f0ec8ab742007f.png" class="" title="d07daa2a1fea9dc43f540e689ebb76b2.png"></li>
<li>进入这个函数我们可以看到它进行了一些编译oat之前的准备工作，之后调用Exec()执行编译，跟进看一下</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/c4163c2dc34e432c96c7242933013e7f.png" class="" title="aff6c9b13fa6d18a8f7ebf4d609e7f5c.png">
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/e76a3f1a9e694adcb36b502c1bc38db2.png" class="" title="4e1c2058e543a27a12af1476ca3a47f3.png">

<ul>
<li>进来之后看到它执行了ExecAndReturnCode()，继续跟进看一下<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/4fc6a3f1260a40689379e96ecf593afc.png" class="" title="89b1b54df2ed18cdc871cac2ada04ee5.png"></li>
<li>进来这个函数之后，可以看到源码中创建新的进程来开始执行execve()来执行Dex2Oat的编译。<br><strong>到这里先暂停一下，接下来我们来分析如果这个壳不执行Dex2Oat它的编译流程</strong></li>
</ul>
<p><strong>在这整个流程当中如果我们把函数执行的流程进行了修改或者hook，就会导致Dex2Oat流程的结束。如果我们去强制结束这个Dex2Oat的流程是可以让DexClassLoader在第一次加载dex这个过程变得非常的快速，减省去执行Dex2Oat编译花费的时间。如果要实现ART下的函数抽取技术，我们也就需要阻断掉Dex2Oat的流程。这就是ART下的函数抽取实现方案和Dalvik下的区别，因为在Dalvik下不存在Dex2Oat的编译流程。</strong></p>
<p>如果我们阻断这个流程呢，oat文件就无法生成了，就会在前面判断的时候跳转到加载dex文件的分支</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/b39c3705ca0e4fd49814759c128364d0.png" class="" title="e7d449b26a5cb3cf37bb2949773f0837.png">
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/31e56ded535d46f58f875c328a22be25.png" class="" title="4792f57c18a16f41c851dc9569a25a5d.png">

<ul>
<li>转而加载dex文件，在这里面我们跟进它调用的DexFile::Open()看一下<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/69a05ede94354e57ad646644ae40cc5a.png" class="" title="66aabfdc0c55694969262ec212349e6b.png"></li>
<li>这个文件里面Open()重载比较多，根据传入参数的类型找到这个Open()。在里面可以看到它调用了OpenAndReadMagic()</li>
</ul>
<p>这个函数是在devcon上来自Check Point的安全研究人员所使用的其中一个脱壳点<br><code>File fd = OpenAndReadMagic(filename, &amp;magic, error_msg);</code></p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/b395c12b8c394a03b3e960b8b22b8d6c.png" class="" title="5379554748e3c0ce442bd4ba9826e4f7.png">

<ul>
<li><p>不过这个脱壳点并不是很好，因为此时dex文件还没有加载到内存中，因为是dex文件所以接下来会执行到DexFile::OpenFile()中去，跟进去看一下</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/992ee61e4b454ba6a27a494650256912.png" class="" title="a6f4a285cc565b1a7bf9bc9c138ab25e.png">
</li>
<li><p>在这里我们可以看到将文件映射到了内存，之后又进入了OpenCommon()继续跟进</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/718358cf7bd34210b037654507e26d85.png" class="" title="42be0a33f6dea978812cedf9e6ded676.png">
</li>
<li><p>OpenCommon()这里也有基址和大小，所以这个位置也可以作为一个脱壳点，</p>
<pre><code class="C++">std::unique_ptr&lt;DexFile&gt; DexFile::OpenCommon(const uint8_t* base,
                                             size_t size,
                                             const std::string&amp; location,
                                             uint32_t location_checksum,
                                             const OatDexFile* oat_dex_file,
                                             bool verify,
                                             bool verify_checksum,
                                             std::string* error_msg,
                                             VerifyResult* verify_result)
</code></pre>
</li>
<li><p>接下来的流程又进入了new DexFile()继续跟进</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/2503e48477b340b88c222510ea31ba44.png" class="" title="6468067e203efe41edae9148dad4196d.png">
</li>
<li><p>这里也有基址和大小可以作为我们的一个脱壳点</p>
</li>
</ul>
<pre><code class="C++">DexFile::DexFile(const uint8_t* base,
                 size_t size,
                 const std::string&amp; location,
                 uint32_t location_checksum,
                 const OatDexFile* oat_dex_file)
</code></pre>
<ul>
<li><p>DexFile()对dex文件的对象进行了初始化，到这里我们就把从禁用Dex2Oat到加载dex文件的流程分析完了</p>
</li>
<li><p>在加载dex文件这个过程中我们找到了三个脱壳点</p>
<ol>
<li><p><code>File fd = OpenAndReadMagic(filename, &amp;magic, error_msg);</code></p>
</li>
<li><pre><code class="C++">std::unique_ptr&lt;DexFile&gt; DexFile::OpenCommon(const uint8_t* base,
                                             size_t size,
                                             const std::string&amp; location,
                                             uint32_t location_checksum,
                                             const OatDexFile* oat_dex_file,
                                             bool verify,
                                             bool verify_checksum,
                                             std::string* error_msg,
                                             VerifyResult* verify_result)
</code></pre>
</li>
<li><pre><code class="C++">DexFile::DexFile(const uint8_t* base,
                 size_t size,
                 const std::string&amp; location,
                 uint32_t location_checksum,
                 const OatDexFile* oat_dex_file)
</code></pre>
</li>
</ol>
</li>
<li><p>这里可以发现第2和第3个脱壳点和我们前面分析<em>InMemoryDexClassLoader</em>流程的时候的脱壳点是重合的，所以不管它使用哪一种ClassLoader去进行dex加载，在经过这两个脱壳点的时候都是可以dump下来的。接下来就实现一下这些脱壳点</p>
</li>
</ul>
<h3 id="修改源码脱壳"><a href="#修改源码脱壳" class="headerlink" title="修改源码脱壳"></a>修改源码脱壳</h3><p>在脱壳点获取内存中dex文件的基址和大小将其dump到文件中</p>
<pre><code class="C++">// 获取当前进程的ID  
int pid = getpid();  
  
// 创建一个字符数组，用于存储dex文件的路径  
char dexFilePath[100] = {0};  
  
// 使用sprintf函数将路径格式化为字符串，并存储在dexFilePath数组中  
// 路径为"/sdcard/"，后面跟着两个整数（size和pid），然后是dex文件的名称"OpenCommon.dex"  
sprintf(dexFilePath, "/sdcard/%d_%d_OpenCommon.dex", (int)size, pid);  
  
// 打开dex文件，使用O_CREAT|O_RDWR标志，文件权限为666（所有用户可读可写）  
int fd = open(dexFilePath, O_CREAT|O_RDWR, 666);  
  
// 如果文件打开成功（文件描述符大于0）  
if(fd &gt; 0){  
    // 向文件中写入数据，数据来源于base指针指向的内存，大小为size  
    int number = write(fd, base, size);  
  
    // 如果写入的字节数大于0，说明写入成功  
    if(number &gt; 0){}  
  
    // 关闭文件  
    close(fd);  
}
</code></pre>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914162835544.png" class="" title="image-20230914162835544">



<p><strong>PS：注意编译Android源码要给虚拟机起码300MB以上的硬盘空间，因为单单只是源码就有一百多G</strong></p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/c352b1080cc14a9ca217dd89cb9a5f24.png" class="" title="ffa6aee3fc0ead0fb0b31e35c8472cad.png">

<p><strong>编译源码命令</strong></p>
<ul>
<li>进入源码目录下执行下面的命令</li>
</ul>
<pre><code>source build/envsetup.sh

lunch

21&lt;根据手机型号选择编译版本&gt;

time make -j4 &lt;线程多开几个编译速度会快点，虚拟机的内存给到16G以上&gt;
</code></pre>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914155304069.png" class="" title="image-20230914155304069">

<center>编译完成</center>

<p>将编译好的img拷贝出来</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914161213587.png" class="" title="image-20230914161213587">

<p>写个bat脚本自动刷机，也可以手动刷机。</p>
<pre><code class="bash">@echo off  
echo entering Fastboot model...  
adb reboot bootloader  
  
echo Locking device...  
fastboot oem unlock  
  
echo Flashing the system image...  
fastboot flash boot boot.img
fastboot flash vendor vendor.img
fastboot flash system_a system.img
fastboot flash system_b system_other.img
fastboot flash userdata userdata.img
  
echo Restarting the device...  
fastboot reboot  
  
echo Flashing is complete!  
pause
</code></pre>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/02ac72275c1c4dfc9aac6193ee5023de.png" class="" title="f1ca3dd4a77c3fe5691952d151ad1257.png">

<center>刷机完成</center>

<h3 id="测试脱壳效果"><a href="#测试脱壳效果" class="headerlink" title="测试脱壳效果"></a>测试脱壳效果</h3><p><strong>PS：测试之前可以先去把<em>sdcard</em>目录下安装系统时候产生的dex文件删除掉，有点多。</strong></p>
<p>先测试一下我们原来自己写的LoadDex，安装apk把dex放在<code>sdcard</code>路径下</p>
<p><code>adb install .\loadDex.apk</code></p>
<p><code>adb push 4.dex /sdcard/</code></p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914155434953.png" class="" title="image-20230914155434953">

<ul>
<li><p>安装完成后在手机系统设置里给apk打开文件访问权限，才能脱壳写文件</p>
</li>
<li><p>设置完之后运行app，然后再*/sdcard/*目录下找到dump下来的dex文件</p>
</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/c2844eb50c5b4fc08553de56a58df482.png" class="" title="0781b10e10116d2149a2310aef57d5a9.png">

<p>然后，新建一个目录将这些文件都pull下来</p>
<ul>
<li><p>先把<em>sdcard</em>目录下的所有dex都放在一个文件夹里，然后把整个文件夹pull下来</p>
<p><code>mkdir /sdcard/dex</code></p>
<p><code>cp *.dex /sdcard/dex</code></p>
</li>
</ul>
<p>在电脑上准备好的目录下执行</p>
<p><code>adb pull /sdcard/dex</code></p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/29e34c1fa4c84ace9e38e0b43754b4a5.png" class="" title="73573295a1ed54ff9e75733069de0ef1.png">

<p>同时我们可以在<em>sdcard</em>目录下的<em>dex</em>文件中搜索TestActivity</p>
<p><code>grep -ril "TestActivity" ./*.dex</code></p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/1d1f3c5174b047bab0a248a1d950d9ea.png" class="" title="4fc1f38f66130ed89540bf68ecfe9cdc.png">

<p>然后用GDA打开这些文件查看一下</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/688afadad884485c87adf0c50cddba50.png" class="" title="3f19bacb4dd0713db2916d61ac1f1980.png">

<ul>
<li>完全正常</li>
</ul>
<p>因为这个apk和dex是我们自己写的使用<em>DexClassLoader</em>加载的，所以肯定是可以dump下来的。我们再拿其它的apk试试。</p>
<p>换了两个app，Express100和货拉拉司机版</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914155735045.png" class="" title="image-20230914155735045">
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/8afea948022543abac1fdd8374ad207e.png" class="" title="6914aacc706ad63fcd7b7472a7407dad.png">

<center>Express100</center>

<ul>
<li>Express100这个dex脱壳正常所有的函数代码都能正常显示，下面试试货拉拉的。</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/image-20230914155936844.png" class="" title="image-20230914155936844">

<center>货拉拉司机版</center>

<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/a2a9c8573cd34b38bf921c16a88118f6.png" class="" title="0d4a5553d8d1f553254cdbf2a7d1a38b.png">

<ul>
<li>货拉拉dump下来的dex打开之后发现函数体都是空的，因为这个壳做了函数抽取的保护方案。这次我们使用的整体脱壳的方案不能应对函数抽取壳的脱壳，下一篇我们处理第二代壳函数抽取壳的问题。</li>
</ul>
<p><strong>小结一下：</strong></p>
<p>前面我们对InMemoryDexClassLOader和Dex2Oat被禁用掉这两个流程进行了脱壳点的总结，找到了它们的脱壳点（虽然大部分壳为了安全都不会这么做，因为执行to oat的时候dex文件时没有加密的），接下来我们再分析一下如果它执行了Dex2Oat怎么脱壳。</p>
<h3 id="进行Dex2Oat流程的脱壳分析"><a href="#进行Dex2Oat流程的脱壳分析" class="headerlink" title="进行Dex2Oat流程的脱壳分析"></a>进行Dex2Oat流程的脱壳分析</h3><p>在前面我们分析到了执行ExecAndReturnCode()的时候，执行到了execve()这个函数的时候就会去调用Dex2Oat()这种方式来加载dex文件</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/b2662afa121249cf88b24d45bf494288.png" class="" title="5194421095811fa941723658bce2ce9e.png">

<ul>
<li>如果这里正常执行过execve()之后，我们就进入到了Dex2Oat的流程当中了</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/e7ca73439a1744b7bb096661dc57e77a.png" class="" title="85ff5583eed7b76fe215941ef27d2bfb.png">

<ul>
<li>这个文件可以看到是一个带有main()的可执行程序，进入main()函数先执行了Dex2Oat()。我们跟进去看看</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/9098a19e7e524694a6568d75c17c6ff3.png" class="" title="4636e02cf9534c96cd7fce1b6a1cf6b7.png">

<ul>
<li>这个函数的前面是对传进来的命令行参数的解析、初始化ART内存映射、检查要编译的dex文件是否可以打开等操作，我们主要跟进dex2oat-&gt;Setup()看一下编译前的设置。</li>
</ul>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/acaf40b185c045fcaeee04c603e2333a.png" class="" title="64d13612569bd45a89941c76b846f8d7.png">

<ul>
<li><p>在Setup()的结尾处呢，会对当前所有的dex文件进行一个遍历确保存活然后注册，我们就可以在这个地方进行dex的脱壳<br>包括还有一些其它的地方也会有对dex内存地址的引用</p>
<img lazyload="" src="/images/loading.svg" data-src="/2023/09/14/ART%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/4e3a19252a3547d19e10ae363f225748.png" class="" title="5b0a1858f7e5c741e488d00e183d1e89.png">
</li>
<li><p>我们需要的时候都可以在这些地方添加脱壳代码进行脱壳。在流程中有很多这种脱壳点，不一个一个找出来了。</p>
</li>
</ul>

		</div>

		
		<div class="post-copyright-info w-full my-8 px-2 sm:px-6 md:px-8">
			<div class="article-copyright-info-container">
    <ul>
        <li><strong>标题:</strong> ART下一代壳通用解决方案</li>
        <li><strong>作者:</strong> xiaoeryu</li>
        <li><strong>创建于
                :</strong> 2023-09-14 00:09:38</li>
        
            <li>
                <strong>更新于
                    :</strong> 2023-09-23 18:15:38
            </li>
        
        <li>
            <strong>链接:</strong> https://github.com/xiaoeryu/2023/09/14/ART下一代壳通用解决方案/
        </li>
        <li>
            <strong>
                版权声明:
            </strong>
            

            
                本文章采用 <a class="license" target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0">CC BY-NC-SA 4.0</a> 进行许可。
            
        </li>
    </ul>
</div>

		</div>
		

		
		<ul class="post-tags-box text-lg mt-1.5 flex-wrap justify-center flex md:hidden">
			
			<li class="tag-item mx-0.5">
				<a href="/tags/Android%E8%84%B1%E5%A3%B3/">#Android脱壳</a>&nbsp;
			</li>
			
			<li class="tag-item mx-0.5">
				<a href="/tags/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">#学习笔记</a>&nbsp;
			</li>
			
			<li class="tag-item mx-0.5">
				<a href="/tags/Android%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90/">#Android源码分析</a>&nbsp;
			</li>
			
			<li class="tag-item mx-0.5">
				<a href="/tags/ART%E8%84%B1%E5%A3%B3/">#ART脱壳</a>&nbsp;
			</li>
			
		</ul>
		

		

		
		<div class="article-nav my-8 flex justify-between items-center px-2 sm:px-6 md:px-8">
			
			<div class="article-prev border-border-color shadow-redefine-flat shadow-shadow-color-2 rounded-medium px-4 py-2 hover:shadow-redefine-flat-hover hover:shadow-shadow-color-2">
				<a class="prev" rel="prev" href="/2023/09/22/ART%E4%B8%8B%E6%8A%BD%E5%8F%96%E5%A3%B3%E5%AE%9E%E7%8E%B0/">
					<span class="left arrow-icon flex justify-center items-center">
						<i class="fa-solid fa-chevron-left"></i>
					</span>
					<span class="title flex justify-center items-center">
						<span class="post-nav-title-item">ART下抽取壳实现</span>
						<span class="post-nav-item">上一篇</span>
					</span>
				</a>
			</div>
			
			
			<div class="article-next border-border-color shadow-redefine-flat shadow-shadow-color-2 rounded-medium px-4 py-2 hover:shadow-redefine-flat-hover hover:shadow-shadow-color-2">
				<a class="next" rel="next" href="/2023/09/04/Dalvik%E4%B8%8B%E4%B8%80%E4%BB%A3%E5%A3%B3%E7%9A%84%E9%80%9A%E7%94%A8%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/">
					<span class="title flex justify-center items-center">
						<span class="post-nav-title-item">Dalvik下一代壳的通用解决方案</span>
						<span class="post-nav-item">下一篇</span>
					</span>
					<span class="right arrow-icon flex justify-center items-center">
						<i class="fa-solid fa-chevron-right"></i>
					</span>
				</a>
			</div>
			
		</div>
		


		
		<div class="comment-container px-2 sm:px-6 md:px-8 pb-8">
			<div class="comments-container mt-10 w-full ">
    <div id="comment-anchor" class="w-full h-2.5"></div>
    <div class="comment-area-title w-full my-1.5 md:my-2.5 text-xl md:text-3xl font-bold">
        评论
    </div>
    

        
            


        
    
</div>

		</div>
		
	</div>

	
	<div class="toc-content-container">
		<div class="post-toc-wrap">
	<div class="post-toc">
		<div class="toc-title">目录</div>
		<div class="page-title">ART下一代壳通用解决方案</div>
		<ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#InMemoryDexClassLoader%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90"><span class="nav-text">InMemoryDexClassLoader源码分析</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#DexClassLoader%E5%8A%A0%E8%BD%BD%E6%BA%90%E7%A0%81%E6%B5%81%E7%A8%8B%E5%88%86%E6%9E%90"><span class="nav-text">DexClassLoader加载源码流程分析</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%B7%9F%E8%BF%9Bnative%E5%B1%82"><span class="nav-text">跟进native层</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E4%BF%AE%E6%94%B9%E6%BA%90%E7%A0%81%E8%84%B1%E5%A3%B3"><span class="nav-text">修改源码脱壳</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B5%8B%E8%AF%95%E8%84%B1%E5%A3%B3%E6%95%88%E6%9E%9C"><span class="nav-text">测试脱壳效果</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E8%BF%9B%E8%A1%8CDex2Oat%E6%B5%81%E7%A8%8B%E7%9A%84%E8%84%B1%E5%A3%B3%E5%88%86%E6%9E%90"><span class="nav-text">进行Dex2Oat流程的脱壳分析</span></a></li></ol></li></ol>

	</div>
</div>
	</div>
	
</div>
			</div>

			
		</div>

		<div class="main-content-footer">
			<footer class="footer mt-5 py-5 h-auto text-base text-third-text-color relative border-t-2 border-t-border-color">
    <div class="info-container py-3 text-center">
        
        <div class="text-center">
            &copy;
            
              <span>2022</span>
              -
            
            2025&nbsp;&nbsp;<i class="fa-solid fa-heart fa-beat" style="--fa-animation-duration: 0.5s; color: #f54545"></i>&nbsp;&nbsp;<a href="/">xiaoeryu</a>
            
                
                <p class="post-count space-x-0.5">
                    <span>
                        共撰写了 112 篇文章
                    </span>
                    
                </p>
            
        </div>
        
            <script data-swup-reload-script src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
            <div class="relative text-center lg:absolute lg:right-[20px] lg:top-1/2 lg:-translate-y-1/2 lg:text-right">
                
                    <span id="busuanzi_container_site_uv" class="lg:!block">
                        <span class="text-sm">访问人数</span>
                        <span id="busuanzi_value_site_uv"></span>
                    </span>
                
                
                    <span id="busuanzi_container_site_pv" class="lg:!block">
                        <span class="text-sm">总访问量</span>
                        <span id="busuanzi_value_site_pv"></span>
                    </span>
                
            </div>
        
        <div class="relative text-center lg:absolute lg:left-[20px] lg:top-1/2 lg:-translate-y-1/2 lg:text-left">
            <span class="lg:block text-sm">由 <?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="relative top-[2px] inline-block align-baseline" version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="1rem" height="1rem" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve"><path fill="#0E83CD" d="M256.4,25.8l-200,115.5L56,371.5l199.6,114.7l200-115.5l0.4-230.2L256.4,25.8z M349,354.6l-18.4,10.7l-18.6-11V275H200v79.6l-18.4,10.7l-18.6-11v-197l18.5-10.6l18.5,10.8V237h112v-79.6l18.5-10.6l18.5,10.8V354.6z"/></svg><a target="_blank" class="text-base" href="https://hexo.io">Hexo</a> 驱动</span>
            <span class="text-sm lg:block">主题&nbsp;<a class="text-base" target="_blank" href="https://github.com/EvanNotFound/hexo-theme-redefine">Redefine v2.8.2</a></span>
        </div>
        
        
            <div>
                博客已运行 <span class="odometer" id="runtime_days" ></span> 天 <span class="odometer" id="runtime_hours"></span> 小时 <span class="odometer" id="runtime_minutes"></span> 分钟 <span class="odometer" id="runtime_seconds"></span> 秒
            </div>
        
        
            <script data-swup-reload-script>
                try {
                    function odometer_init() {
                    const elements = document.querySelectorAll('.odometer');
                    elements.forEach(el => {
                        new Odometer({
                            el,
                            format: '( ddd).dd',
                            duration: 200
                        });
                    });
                    }
                    odometer_init();
                } catch (error) {}
            </script>
        
        
        
    </div>  
</footer>
		</div>
	</div>

	
	<div class="post-tools">
		<div class="post-tools-container">
	<ul class="article-tools-list">
		<!-- TOC aside toggle -->
		
		<li class="right-bottom-tools page-aside-toggle">
			<i class="fa-regular fa-outdent"></i>
		</li>
		

		<!-- go comment -->
		
		<li class="go-comment">
			<i class="fa-regular fa-comments"></i>
		</li>
		
	</ul>
</div>
	</div>
	

	<div class="right-side-tools-container">
		<div class="side-tools-container">
	<ul class="hidden-tools-list">
		<li class="right-bottom-tools tool-font-adjust-plus flex justify-center items-center">
			<i class="fa-regular fa-magnifying-glass-plus"></i>
		</li>

		<li class="right-bottom-tools tool-font-adjust-minus flex justify-center items-center">
			<i class="fa-regular fa-magnifying-glass-minus"></i>
		</li>

		<li class="right-bottom-tools tool-dark-light-toggle flex justify-center items-center">
			<i class="fa-regular fa-moon"></i>
		</li>

		<!-- rss -->
		

		

		<li class="right-bottom-tools tool-scroll-to-bottom flex justify-center items-center">
			<i class="fa-regular fa-arrow-down"></i>
		</li>
	</ul>

	<ul class="visible-tools-list">
		<li class="right-bottom-tools toggle-tools-list flex justify-center items-center">
			<i class="fa-regular fa-cog fa-spin"></i>
		</li>
		
		<li class="right-bottom-tools tool-scroll-to-top flex justify-center items-center">
			<i class="arrow-up fas fa-arrow-up"></i>
			<span class="percent"></span>
		</li>
		
		
	</ul>
</div>
	</div>

	<div class="image-viewer-container">
	<img src="">
</div>

	
	<div class="search-pop-overlay">
	<div class="popup search-popup">
		<div class="search-header">
			<span class="search-input-field-pre">
				<i class="fa-solid fa-keyboard"></i>
			</span>
			<div class="search-input-container">
				<input autocomplete="off" autocorrect="off" autocapitalize="off" placeholder="站内搜索您需要的内容..." spellcheck="false" type="search" class="search-input">
			</div>
			<span class="popup-btn-close">
				<i class="fa-solid fa-times"></i>
			</span>
		</div>
		<div id="search-result">
			<div id="no-result">
				<i class="fa-solid fa-spinner fa-spin-pulse fa-5x fa-fw"></i>
			</div>
		</div>
	</div>
</div>
	

</main>



<script src="/js/build/libs/Swup.min.js"></script>

<script src="/js/build/libs/SwupSlideTheme.min.js"></script>

<script src="/js/build/libs/SwupScriptsPlugin.min.js"></script>

<script src="/js/build/libs/SwupProgressPlugin.min.js"></script>

<script src="/js/build/libs/SwupScrollPlugin.min.js"></script>

<script src="/js/build/libs/SwupPreloadPlugin.min.js"></script>

<script>
    const swup = new Swup({
        plugins: [
            new SwupScriptsPlugin({
                optin: true,
            }),
            new SwupProgressPlugin(),
            new SwupScrollPlugin({
                offset: 80,
            }),
            new SwupSlideTheme({
                mainElement: ".main-content-body",
            }),
            new SwupPreloadPlugin(),
        ],
        containers: ["#swup"],
    });
</script>




	
<script src="/js/build/tools/imageViewer.js" type="module"></script>

<script src="/js/build/utils.js" type="module"></script>

<script src="/js/build/main.js" type="module"></script>

<script src="/js/build/layouts/navbarShrink.js" type="module"></script>

<script src="/js/build/tools/scrollTopBottom.js" type="module"></script>

<script src="/js/build/tools/lightDarkSwitch.js" type="module"></script>

<script src="/js/build/layouts/categoryList.js" type="module"></script>



    
<script src="/js/build/tools/localSearch.js" type="module"></script>




    
<script src="/js/build/tools/codeBlock.js" type="module"></script>




    
<script src="/js/build/layouts/lazyload.js" type="module"></script>




    
<script src="/js/build/tools/runtime.js"></script>

    
<script src="/js/build/libs/odometer.min.js"></script>

    
<link rel="stylesheet" href="/assets/odometer-theme-minimal.css">




  
<script src="/js/build/libs/Typed.min.js"></script>

  
<script src="/js/build/plugins/typed.js" type="module"></script>








    
<script src="/js/build/libs/anime.min.js"></script>





    
<script src="/js/build/tools/tocToggle.js" type="module" data-swup-reload-script=""></script>

<script src="/js/build/layouts/toc.js" type="module" data-swup-reload-script=""></script>

<script src="/js/build/plugins/tabs.js" type="module" data-swup-reload-script=""></script>




<script src="/js/build/libs/moment-with-locales.min.js" data-swup-reload-script=""></script>


<script src="/js/build/layouts/essays.js" type="module" data-swup-reload-script=""></script>





	
</body>

</html>